// import com.alibaba.druid.sql.ast.SQLExpr_ptr ;
// import com.alibaba.druid.sql.ast.SQLName;
// import com.alibaba.druid.sql.ast.SQLSubPartitionBy;
// import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
// import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObject;
// import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

#include "MySqlSubPartitionByValue.h"

#include "../../../../../sql/ast/SQLExpr.h"
#include "../../../../../sql/visitor/SQLASTVisitor.h"
#include "../../../../../sql/dialect/mysql/visitor/MySqlASTVisitor.h"
#include "../../../../../utils/instanceof.h"
#include "../../../../../utils/listTran.h"
#include "../../../../../utils/log.h"
#include "../../../../../Exception/IllegalArgumentException.h"
#include "../../../../../sql/ast/expr/SQLMethodInvokeExpr.h"
#include "../../../../ast/SQLName.h"

MySqlSubPartitionByValue::MySqlSubPartitionByValue()
{
  columns = std::make_shared<std::list<SQLExpr_ptr>>();
}

// @Override
void MySqlSubPartitionByValue::accept0(SQLASTVisitor_ptr visitor)
{
  if (instanceof <SQLASTVisitor, MySqlASTVisitor>(visitor.get()))
  {
    MySqlASTVisitor_ptr tmp = std::dynamic_pointer_cast<MySqlASTVisitor>(visitor);
    accept0(tmp);
  }
  else
  {
    throw new IllegalArgumentException(make_string_ptr("not support visitor type : " + *visitor->getClass()));
  }
}

// @Override
void MySqlSubPartitionByValue::accept0(MySqlASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(MySqlSubPartitionByValue)))
  {
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLExpr, SQLObject>(columns);
    acceptChild(visitor, tmp1);
    acceptChild(visitor, subPartitionsCount);
  }
  visitor->endVisit(SharedObject(MySqlSubPartitionByValue));
}

SQLExpr_list_ptr MySqlSubPartitionByValue::getColumns()
{
  return columns;
}

void MySqlSubPartitionByValue::addColumn(SQLExpr_ptr column)
{
  if (column != nullptr)
  {
    column->setParent(SharedObject(MySqlSubPartitionByValue));
  }
  this->columns->push_back(column);
}

void MySqlSubPartitionByValue::cloneTo(MySqlSubPartitionByValue_ptr x)
{
  SQLSubPartitionBy::cloneTo(x);
  for (SQLExpr_ptr column : *columns)
  {
    SQLExpr_ptr c2 = std::dynamic_pointer_cast<SQLExpr>(column->clone());
    c2->setParent(x);
    x->columns->push_back(c2);
  }
}

SQLObject_ptr MySqlSubPartitionByValue::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<MySqlSubPartitionByValue>(new MySqlSubPartitionByValue());
  std::shared_ptr<MySqlSubPartitionByValue> x = std::dynamic_pointer_cast<MySqlSubPartitionByValue>(clone_tmp);
  // MySqlSubPartitionByValue *x = new MySqlSubPartitionByValue();
  cloneTo(x);
  return x;
}

BOOL_ptr MySqlSubPartitionByValue::isPartitionByColumn(long columnNameHashCode64)
{
  for (SQLExpr_ptr column : *columns)
  {
    if (instanceof <SQLExpr, SQLName>(column))
    {
      if ((std::dynamic_pointer_cast<SQLName>(column))->nameHashCode64() == columnNameHashCode64)
      {
        return BOOL::TRUE;
      }
      else if (instanceof <SQLExpr, SQLMethodInvokeExpr>(column))
      {
        SQLExpr_list_ptr arguments = (std::dynamic_pointer_cast<SQLMethodInvokeExpr>(column))->getArguments();
        for (SQLExpr_ptr argument : *arguments)
        {
          if ((std::dynamic_pointer_cast<SQLName>(argument))->nameHashCode64() == columnNameHashCode64)
          {
            return BOOL::TRUE;
          }
        }
      }
    }
  }
  return BOOL::FALSE;
}
